//
// Copyright (c) 2009 All Right Reserved
//
// Stephen Toub
// stoub@microsoft.com
// 2009-01-01
// Contains ...
namespace LargoCommon.Midi
{
using System;
using System.IO;
using System.Text;
using JetBrains.Annotations;
using Music;
/// Represents a voice category message.
[Serializable]
public abstract class VoiceEvent : MidiEvent
{
#region Fields
/// The status identifier (0x0 through 0xF) for this voice event.
private readonly byte category;
#endregion
#region Constructors
/// Initializes a new instance of the VoiceEvent class.
/// The amount of time before this event.
/// The category identifier (0x0 through 0xF) for this voice event.
/// The channel (0x0 through 0xF) for this voice event.
protected VoiceEvent(long deltaTime, byte givenCategory, MidiChannel channel)
: base(deltaTime) {
// Validate the parameters
if (givenCategory > 0xF) {
throw new ArgumentOutOfRangeException(nameof(givenCategory), givenCategory, "Category values must be in the range from 0x0 to 0xF.");
}
// Store the data
this.category = givenCategory;
this.Channel = channel;
}
/// Initializes a new instance of the VoiceEvent class.
/// The amount of time before this event.
protected VoiceEvent(long deltaTime)
: base(deltaTime) {
}
#endregion
#region Properties
/// Gets The first parameter as sent in the MIDI message.
/// General musical property.
public abstract byte Parameter1 { get; }
/// Gets The second parameter as sent in the MIDI message.
/// General musical property.
public abstract byte Parameter2 { get; }
/// Gets the status identifier (0x0 through 0xF) for this voice event.
/// General musical property.
[UsedImplicitly]
public byte Category => this.category;
/// Gets or sets the channel (0x0 through 0xF) for this voice event.
/// General musical property.
public MidiChannel Channel { get; set; } //// virtual (11/2010)
/// Gets the status byte for the event message (combination of category and channel).
/// General musical property.
public byte Status => this.GetStatusByte();
/// Gets the word that represents this event as a MIDI event message.
[UsedImplicitly]
internal int Message => this.Status | (this.Parameter1 << 8) | (this.Parameter2 << 16);
#endregion
#region To String
/// Generate a string representation of the event.
/// A string representation of the event.
public override string ToString() {
var sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append(" \t");
sb.Append("C=" + this.Channel);
//// sb.Append("\t");
//// sb.Append("0x");
//// sb.Append(this.Channel.ToString("X1", System.Globalization.CultureInfo.CurrentCulture.NumberFormat));
return sb.ToString();
}
#endregion
#region Methods
/// Write the event to the output stream.
/// The stream to which the event should be written.
public override void Write(Stream outputStream) {
if (outputStream == null) {
return;
}
//// Write out the base event information
base.Write(outputStream);
// Write out the status byte
outputStream.WriteByte(this.GetStatusByte());
}
/// Gets the status byte for the message event.
/// The status byte (combination of category and channel) for the message event.
private byte GetStatusByte() {
// The command is the upper 4 bits and the channel is the lower 4.
return (byte)((this.category << 4) | (byte)this.Channel); //// was cast to int before this.category
}
#endregion
}
}